﻿using Common.FrontEnd;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Util;

namespace Common
{
    public interface IResult
    {
        /// <summary>
        ///Determines if the result is a final result. A final result is guaranteed to no longer be
        ///modified by the SearchManager that generated it. Non-final results can be modifed by a
        ///<code>SearchManager.recognize</code> calls.
        ///@return true if the result is a final result
        /// <summary>
        Boolean isFinal();

        /// <summary>
        ///Returns the log math used for this Result.
        ///
        ///@return the log math used
        /// <summary>
        LogMath getLogMath();
        /// <summary>
        ///Returns a list of active tokens for this result. The list contains zero or active
        ///<code>Token</code> objects that represents the leaf nodes of all active branches in the
        ///result (sometimes referred to as the 'lattice').
        ///<p/>
        ///The lattice is live and may be modified by a SearchManager during a recognition. Once the
        ///Result is final, the lattice is fixed and will no longer be modified by the SearchManager.
        ///Applications can modify the lattice (to prepare for a re-recognition, for example) only after
        ///<code>isFinal</code> returns <code>true</code>
        ///
        ///@return a list containing the active tokens for this result
        ///@see Token
        /// <summary>
        IActiveList getActiveTokens();

        /// <summary>
        ///Returns a list of result tokens for this result. The list contains zero or more result
        ///<code>Token</code> objects that represents the leaf nodes of all final branches in the result
        ///(sometimes referred to as the 'lattice').
        ///<p/>
        ///The lattice is live and may be modified by a SearchManager during a recognition. Once the
        ///Result is final, the lattice is fixed and will no longer be modified by the SearchManager.
        ///Applications can modify the lattice (to prepare for a re-recognition, for example) only after
        ///<code>isFinal</code> returns <code>true</code>
        ///
        ///return a list containing the final result tokens for this result
        ///see Token
        /// <summary>
        /// 
        List<IToken> getResultTokens();

        /// <summary>
        ///Returns the AlternateHypothesisManager Used to construct a Lattice
        ///
        ///@return the AlternateHypothesisManager
        /// <summary>
        IAlternateHypothesisManager getAlternateHypothesisManager();

        /// <summary>
        ///Returns the current frame number
        ///
        ///@return the frame number
        /// <summary>
        int getFrameNumber();

        /// <summary>
        ///Returns the best scoring final token in the result. A final token is a token that has reached
        ///a final state in the current frame.
        ///
        ///@return the best scoring final token or null
        /// <summary>
        IToken getBestFinalToken();

        /// <summary>
        ///Returns the best scoring token in the result. First, the best final token is retrieved. A
        ///final token is one that has reached the final state in the search space. If no final tokens
        ///can be found, then the best, non-final token is returned.
        ///
        ///@return the best scoring token or null
        /// <summary>
        IToken getBestToken();

        /// <summary>
        ///Returns the best scoring token in the active set
        ///
        ///@return the best scoring token or null
        /// <summary>
        IToken getBestActiveToken();
        /// <summary>
        ///Searches through the n-best list to find the the branch that matches the given string
        ///
        ///@param text the string to search for
        ///@return the token at the head of the branch or null
        /// <summary>
        IToken findToken(String text);
        /// <summary>
        ///Searches through the n-best list to find the the branch that matches the beginning of the
        ///given string
        ///
        ///@param text the string to search for
        ///@return the list token at the head of the branch
        /// <summary>
        List<IToken> findPartialMatchingTokens(String text);
        /// <summary>
        ///Returns the best scoring token that matches the beginning of the given text.
        ///
        ///@param text the text to match
        /// <summary>
        IToken getBestActiveParitalMatchingToken(String text);

        /// <summary>
        ///Returns detailed frame statistics for this result
        ///
        ///@return frame statistics for this result as an array, with one element per frame or
        ///        <code>null</code> if no frame statistics are available.
        /// <summary>
        IFrameStatistics[] getFrameStatistics();
        
        /// <summary>
        ///Gets the starting frame number for the result. Note that this method is currently not
        ///implemented, and always returns zero.
        ///
        ///@return the starting frame number for the result
        /// <summary>
        int getStartFrame();

        /// <summary>
        ///Gets the ending frame number for the result. Note that this method is currently not
        ///implemented, and always returns zero.
        ///
        ///@return the ending frame number for the result
        /// <summary>
        int getEndFrame();
        
        /// <summary>
        ///Gets the feature frames associated with this result
        ///
        ///@return the set of feature frames associated with this result, or null if the frames are not
        ///        available.
        /// <summary>
        List<IData> getDataFrames();

        /// <summary>
        ///Returns the string of the best result, removing any filler words. This method first attempts
        ///to return the best final result, that is, the result that has reached the final state of the
        ///search space. If there are no best final results, then the best non-final result, that is,
        ///the one that did not reach the final state, is returned.
        ///
        ///@return the string of the best result, removing any filler words
        /// <summary>
        String getBestResultNoFiller();

        /// <summary>
        ///Returns the string of the best final result, removing any filler words. A final result is a
        ///path that has reached the final state. A Result object can also contain paths that did not
        ///reach the final state, and those paths are not returned by this method.
        ///
        ///@return the string of the best result, removing any filler words, or null if there are no
        ///        best results
        /// <summary>
        String getBestFinalResultNoFiller();


        /// <summary>
        ///The method is used when the application wants the phonemes on the best final path. Note that
        ///words may have more than one pronunciation, so this is not equivalent to the word path e.g.
        ///one[HH,W,AH,N] to[T,UW] three[TH,R,IY]
        ///
        ///@return the String of words and associated phonemes on the best path
        /// <summary>
        String getBestPronunciationResult();

        /// <summary>
        ///Returns the string of words (with timestamp) for this token.
        ///
        ///@param withFillers true if we want filler words included, false otherwise
        ///@param wordTokenFirst true if the word tokens come before other types of tokens
        ///@return the string of words
        /// <summary>
        List<IWordResult> getTimedBestResult(Boolean withFillers);

        /// <summary>
        ///Returns the string of words (with timestamp) for this token. This method assumes that the
        ///word tokens come before other types of token.
        ///
        ///@param withFillers true if we want filler words, false otherwise
        ///@return list of word with timestamps
        /// <summary>
        List<IWordResult> getTimedWordPath(IToken token, Boolean withFillers);

        /// <summary>
        ///Returns the string of words for this token, each with the starting sample number as the
        ///timestamp. This method assumes that the word tokens come after the unit and hmm tokens.
        ///
        ///@return the string of words, each with the starting sample number
        /// <summary>
        List<IWordResult> getTimedWordTokenLastPath(IToken token, Boolean withFillers);

        /// <summary> Returns a string representation of this object/// <summary>
        String ToString();

        /// <summary>
        ///Sets the results as a final result
        ///
        ///@param finalResult if true, the result should be made final
        /// <summary>
        void setFinal(Boolean finalResult);
        

        /// <summary>
        ///Determines if the Result is valid. This is used for testing and debugging
        ///
        /// @return true if the result is properly formed.
        /// <summary>
        Boolean validate();
        

        /// <summary>
        ///Sets the reference text
        ///
        ///@param ref the reference text
        /// <summary>
        void setReferenceText(String _ref);
        /// <summary>
        ///Retrieves the reference text. The reference text is a transcript of the text that was spoken.
        ///
        ///@return the reference text or null if no reference text exists.
        /// <summary>
        String getReferenceText();

    }
}
